package client

import (
	. "chess_platform/internal/common"
	"chess_platform/models/pc"
	"fmt"
	"github.com/astaxie/beego/orm"
	"strconv"
)

var (
	ServerCfgCacheTime = 300 //5分钟
)

// 获得当前启用服务器组
func GetCurSvrGroup() int64 {
	group, err := Redis.GetInt64(KeyCurSvrGroup)
	if err != nil {
		LogClient.Error(fmt.Sprintf("---出错了，所以返回默认服务组:1-----------服务组group:%v,err:%v", group, err))
		return 1
	}
	return group
}
func SetCurSvrGroup(group int64) {
	//NotifyStopServer()
	Redis.Set(KeyCurSvrGroup, group)
	NotifyStopServer()
}

// 获得大厅服务器地址
func GetLobbyServerIpByUid(uid, group int64) (ip ServerLobby, err error) {
	var res []ServerLobby
	key := fmt.Sprintf("%v%v", KeyLobbyIp, group)
	err = GetCache(MemCache, key, &res)
	if err != nil {
		o := NewDBOrm(DBChessSysData)
		sql := fmt.Sprintf("SELECT svrid,svrip,svrport,onlines FROM %v WHERE svr_type = %v AND `group`=%v AND `state`=1",
			TableServerInfo, SERVER_TYPE_LOBBY, group)
		_, err = o.Raw(sql).QueryRows(&res)
		if err != nil {
			return
		}
		SetCache(MemCache, key, res, ServerCfgCacheTime)
	}
	return selectLobbyServerIp(uid, res)
}

// 获取匹配大厅服务器
func selectLobbyServerIp(uid int64, lobbys []ServerLobby) (ip ServerLobby, err error) {
	lobbyid := GetPlayerOnlineRedisInfo(uid, "lsid")
	gameid := GetPlayerOnlineRedisInfo(uid, "gsid")
	if gameid != 0 {
		LogClient.Debug("玩家:%v 在线游戏服务器:%v ", uid, gameid)
	}
	if lobbyid != 0 {
		LogClient.Debug("玩家:%v 在线大厅服务器:%v ", uid, lobbyid)
	}
	//TODO: 切服热更，考虑是否在游戏服,toney待修改
	if lobbyid != 0 && gameid != 0 {
		for _, v := range lobbys {
			if v.Svrid == lobbyid {
				return v, nil
			}
		} //不在同组
		ip, err = GetLobbyServerIpBySvrID(lobbyid)
		if err == nil {
			LogClient.Debug("玩家 %v 在切服后还在游戏中,重连原来的大厅服务器:%v", uid, ip)
			return ip, nil
		}
	}
	//TODO:要把不健康的大厅IP剔除
	if len(lobbys) > 0 {
		return lobbys[uid%int64(len(lobbys))], nil
	}
	return
}

// 获取指定大厅服务器信息
func GetLobbyServerIpBySvrID(svrid int) (ip ServerLobby, err error) {
	var res []ServerLobby
	o := NewDBOrm(DBChessSysData)
	sql := fmt.Sprintf("SELECT svrid,svrip,svrport,onlines,svrlanip FROM %v WHERE svr_type = %v AND `svrid`=%v AND `state`=1",
		TableServerInfo, SERVER_TYPE_LOBBY, svrid)
	_, err = o.Raw(sql).QueryRows(&res)
	if err != nil {
		return
	}
	if len(res) > 0 {
		ip = res[0]
	}
	return
}

// 获得大厅服务器地址
func GetLobbyServerPhpIp(uid, group int64) (ip ServerLobby, err error) {
	var res []ServerLobby
	key := fmt.Sprintf("%v%v", KeyLobbyPhpIp, group)
	err = GetCache(MemCache, key, &res)
	if err != nil {
		o := NewDBOrm(DBChessSysData)
		_, err = o.Raw("SELECT svrid,svrip,phpport,onlines,svrlanip FROM "+
			TableServerInfo+" WHERE svr_type=? AND `group`=? AND `state`=1", SERVER_TYPE_LOBBY, group).QueryRows(&res)
		if CheckNoExist(err) {
			return
		}
		SetCache(MemCache, key, res, ServerCfgCacheTime)
	}
	return selectLobbyServerIp(uid, res)
}

// 获得大厅服务器地址
func GetLobbyServerAllPhpIp(group int64) ([]ServerLobby, error) {
	var res []ServerLobby
	key := fmt.Sprintf("%v%v", KeyLobbyAllPhpIp, group)
	err := GetCache(MemCache, key, &res)
	if err != nil {
		o := NewDBOrm(DBChessSysData)
		_, err = o.Raw("SELECT svrid,svrip,phpport,onlines,svrlanip FROM "+
			TableServerInfo+" WHERE svr_type=? AND `group`=? AND `state`=1",
			SERVER_TYPE_LOBBY, group).QueryRows(&res)
		if CheckNoExist(err) {
			return res, err
		}
		SetCache(MemCache, key, res, ServerCfgCacheTime)
	}
	return res, nil
}

func UserCityCode(uid int64) int64 {
	//先找出玩家所在城市
	sql := fmt.Sprintf("SELECT city_code FROM %v WHERE uid = ?", TableClientUser)
	o := NewDBOrm(DBChess)
	var CityCode int64
	err := o.Raw(sql, uid).QueryRow(&CityCode)
	if CheckError(err) {
		return 0
	}
	return CityCode
}

//根据区或来查游戏列表
func ListAreaGame(cityCode interface{}) ([]orm.Params, error) {
	//显示的当前区域已上线的游戏
	sql := fmt.Sprintf(`
		SELECT
			a.position,g.*
		FROM
			%v AS a
		LEFT JOIN
			%v AS g
		ON a.game_id = g.game_id
		WHERE
			a.city_code = ? AND g.is_publish = 1
		ORDER BY
			a.position
		`, TableAreaGameList, TableGameList)
	var gameList []orm.Params
	o := NewDBOrm(DBChessSysData)
	_, err := o.Raw(sql, cityCode).Values(&gameList)
	if CheckNoExist(err) {
		return gameList, nil
	}

	for _, v := range gameList {
		v["position"], _ = strconv.Atoi(fmt.Sprintf("%v", v["position"]))
		v["room_rule"], err = pc.ListRoomCard(v["game_id"], o)
	}

	return gameList, err
}

//获取全国游戏列表
func ListNationalGame() ([]orm.Params, error) {
	return ListAreaGame(NationCode)
}

//列出全部游戏列表
func ListAllGame(typ int64) ([]orm.Params, error) {
	var gl []orm.Params
	gl, err := GetSliceCache(KeyAllGame)
	if len(gl) == 0 {
		LogClient.Debug(fmt.Sprintf("-----------全部游戏不在缓存里,报的信息:%v", err))
		where := " is_publish = 1 "
		if typ != 0 {
			where = where + fmt.Sprintf(" AND type = %v", typ)
		}
		//显示的全部已上线的游戏
		sql := fmt.Sprintf(`
		SELECT
			*
		FROM
			%v
		WHERE
			%v
		`, TableGameList, where)
		o := NewDBOrm(DBChessSysData)
		_, err := o.Raw(sql).Values(&gl)
		if CheckNoExist(err) {
			return gl, nil
		} else if err != nil {
			return gl, err
		}
		//获取每款游戏的游戏规则
		for _, v := range gl {
			v["room_rule"], _ = pc.ListRoomCard(v["game_id"], o)
		}
		SetSliceCache(KeyAllGame, gl, CacheExpireTenSecond)
	} else {
		LogClient.Debug("-------------全部游戏在缓存里")
	}
	return gl, nil
}
